package com.chagee.store.operation.server.config;

import com.chagee.base.exception.SoaException;
import com.chagee.base.utils.HttpResponse;
import com.chagee.base.utils.HttpResponseUtil;
import com.chagee.store.operation.common.exception.BizErrorCode;
import com.chagee.store.operation.common.exception.BizException;
import com.chagee.store.operation.common.exception.ParamBizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.NotReadablePropertyException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import javax.validation.ValidationException;
import java.net.BindException;

/**
 * 请求参数校验
 *
 * @author yangyang
 * @date 2024/1/24 17:05
 */
@RestControllerAdvice
@Slf4j
public class CommonExceptionHandler {

	@ExceptionHandler({MethodArgumentNotValidException.class})
	@ResponseStatus(HttpStatus.OK)
	@ResponseBody
	public HttpResponse<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
		log.warn("Exception handler", e);
		return HttpResponseUtil.build(null, BizErrorCode.REQUEST_VALID_FAILED.getErrorCode(), e.getBindingResult().getAllErrors().stream().findFirst().map(
			DefaultMessageSourceResolvable::getDefaultMessage).orElse(BizErrorCode.REQUEST_VALID_FAILED.getErrorMsg()));
	}

	@ExceptionHandler({ConstraintViolationException.class})
	@ResponseStatus(HttpStatus.OK)
	@ResponseBody
	public HttpResponse<?> handleConstraintViolationException(ConstraintViolationException ex) {
		log.error("ConstraintViolationException handler", ex);
		return HttpResponseUtil.build(null, BizErrorCode.REQUEST_VALID_FAILED.getErrorCode(), BizErrorCode.REQUEST_VALID_FAILED.getErrorMsg());
	}

	@ExceptionHandler({ValidationException.class})
	@ResponseStatus(HttpStatus.OK)
	@ResponseBody
	public HttpResponse<?> handleValidationException(ValidationException ex) {
		log.error("ValidationException handler", ex);
		return HttpResponseUtil.build(null, BizErrorCode.REQUEST_VALID_FAILED.getErrorCode(), BizErrorCode.REQUEST_VALID_FAILED.getErrorMsg());
	}

	@ExceptionHandler({NotReadablePropertyException.class})
	@ResponseStatus(HttpStatus.OK)
	@ResponseBody
	public HttpResponse<?> handleNotReadablePropertyException(NotReadablePropertyException ex) {
		return HttpResponseUtil.build(null, BizErrorCode.REQUEST_VALID_FAILED.getErrorCode(), BizErrorCode.REQUEST_VALID_FAILED.getErrorMsg());
	}

	@ExceptionHandler(value = BizException.class)
	public HttpResponse<?> bizExceptionHandler(BizException e) {
		log.error("Biz exception handler", e);
		return HttpResponseUtil.build(null, e.getErrorCode(), e.getErrorMsg());
	}

	@ExceptionHandler(value = Exception.class)
	public HttpResponse<?> globalException(Exception e) {
		log.error("Exception handler", e);
		return HttpResponseUtil.failure(BizErrorCode.FAIL);
	}

	@ExceptionHandler(value = {SoaException.class})
	public HttpResponse<?> soaExceptionHandler(SoaException e) {
		log.warn("soaException handler", e);
		return HttpResponseUtil.build(null, e.getErrcode(), e.getErrmsg());
	}

	@ExceptionHandler(value = {BindException.class})
	public HttpResponse<?> bindExceptionHandler(BindException e) {
		log.warn("Exception handler", e);
		return HttpResponseUtil.failure(BizErrorCode.REQUEST_VALID_FAILED);
	}


	@ExceptionHandler(value = ParamBizException.class)
	public HttpResponse<?> paramBizExceptionHandler(ParamBizException e) {
		log.error("param Biz exception handler", e);
		return HttpResponseUtil.build(e.getData(), e.getErrorCode(), e.getErrorMsg());
	}

}
